//
//  Wait for Condition in Current Webpage.m
//  Wait for Condition in Current Webpage
//
//  Created by itod on 4/8/07.
//  Copyright 2007 __MyCompanyName__. All rights reserved.
//

#import "Wait for Condition in Current Webpage.h"
#import <OSAKit/OSAKit.h>

typedef enum {
	TODConditionNotMetPolicyTypeContinue = 0,
	TODConditionNotMetPolicyTypeError
} TODConditionNotMetPolicyType;


@interface Wait_for_Condition_in_Current_Webpage (Private)
- (NSString *)pathForJavaScriptResource:(NSString *)filename;
- (NSString *)conditionFailedDescription;
- (void)resetCurrentSecond;
@end


@implementation Wait_for_Condition_in_Current_Webpage


#pragma mark -
#pragma mark AMBundle

- (void)opened
{
	[self setCurrentSecond:0];
}


#pragma mark -
#pragma mark OttoMateAction

- (NSAppleEventDescriptor *)executeAndReturnError:(NSDictionary **)errorInfo
{
	[self setCurrentSecond:0];
	NSAppleEventDescriptor *desc = nil;
	
	int timeout = [[[self parameters] objectForKey:@"timeout"] intValue];

	BOOL conditionPassed = NO;

	int i;
	for (i = 1; i <= timeout; i++) {
		[self setCurrentSecond:i];
		desc = [super executeAndReturnError:errorInfo];
		
		NSString *retVal = [desc stringValue];
		conditionPassed = [[retVal lowercaseString] hasPrefix:@"true"];
		//NSLog(@"conditionPassed : %d, %d, %d", i, timeout, conditionPassed);
		if (conditionPassed) {
			break;
		}
		[NSThread sleepUntilDate:[NSDate dateWithTimeIntervalSinceNow:1]];
	}
	
	if (!conditionPassed) {
		int policy = [[[self parameters] objectForKey:@"conditionNotMetPolicyType"] intValue];

		if (TODConditionNotMetPolicyTypeError == policy) {
			NSMutableDictionary *d = nil;
			if (*errorInfo) {
				d = [NSMutableDictionary dictionaryWithDictionary:(*errorInfo)];
			} else {
				d = [NSMutableDictionary dictionary];
			}
			
			NSString *errStr = [self conditionFailedDescription];
			
			int i = [[desc stringValue] rangeOfString:@":"].location + 1;
			NSString *urlStr = [[desc stringValue] substringFromIndex:i];
			
			[d setObject:[NSNumber numberWithInt:47] forKey:OSAScriptErrorNumber];
			[d setObject:errStr forKey:OSAScriptErrorMessage];
			[d setObject:errStr forKey:@"OttoMateAssertionFailure"];
			[d setObject:urlStr forKey:@"OttoMateURL"];
			(*errorInfo) = d;
			
			NSLog([(*errorInfo) description]);
			
			[super runAssertionFailedScript:(*errorInfo)];
		}
		
	}
	
	return desc;
}


- (NSString *)javaScriptSource
{
	NSString *string1 = [self objectForParameterKey:@"string1"];
	string1 = (string1) ? string1 : @"";
	NSString *string2 = [self objectForParameterKey:@"string2"];
	string2 = (string2) ? string2 : @"";
	NSString *formIdentifier = [self objectForParameterKey:@"formIdentifier"];
	
	NSString *filename = nil;
	NSMutableString *jsSource = nil;
	
	int assertionType = [[self objectForParameterKey:@"assertionType"] intValue];
	
	switch (assertionType) {
		
		case TODAssertionTypePageTitleEquals:
			filename = @"AssertPageTitleEquals";
			jsSource = [NSString stringWithContentsOfFile:[self pathForJavaScriptResource:filename]];	
			jsSource = [NSString stringWithFormat:jsSource, string1];
			break;
			
		case TODAssertionTypePageHasElementWithId:
			filename = @"AssertPageHasElementWithId";
			jsSource = [NSString stringWithContentsOfFile:[self pathForJavaScriptResource:filename]];	
			jsSource = [NSString stringWithFormat:jsSource, string1];
			break;
			
		case TODAssertionTypePageDoesntHaveElementWithId:
			filename = @"AssertPageDoesntHaveElementWithId";
			jsSource = [NSString stringWithContentsOfFile:[self pathForJavaScriptResource:filename]];	
			jsSource = [NSString stringWithFormat:jsSource, string1];
			break;
			
		case TODAssertionTypePageContainsText:
			filename = @"AssertPageContainsText";
			jsSource = [NSString stringWithContentsOfFile:[self pathForJavaScriptResource:filename]];	
			jsSource = [NSString stringWithFormat:jsSource, string1];
			break;
			
		case TODAssertionTypePageDoesntContainText:
			filename = @"AssertPageDoesntContainText";
			jsSource = [NSString stringWithContentsOfFile:[self pathForJavaScriptResource:filename]];	
			jsSource = [NSString stringWithFormat:jsSource, string1];
			break;
			
		case TODAssertionTypePageContainsHTML:
			filename = @"AssertPagePageContainsHTML";
			jsSource = [NSString stringWithContentsOfFile:[self pathForJavaScriptResource:filename]];	
			jsSource = [NSString stringWithFormat:jsSource, string1];
			break;
			
		case TODAssertionTypePageDoesntContainHTML:
			filename = @"AssertPageDoesntContainHTML";
			jsSource = [NSString stringWithContentsOfFile:[self pathForJavaScriptResource:filename]];	
			jsSource = [NSString stringWithFormat:jsSource, string1];
			break;
			
		case TODAssertionTypeValueForFormElementWithId:
			filename = @"AssertValueForFormElementWithId";
			jsSource = [NSString stringWithContentsOfFile:[self pathForJavaScriptResource:filename]];	
			jsSource = [NSString stringWithFormat:jsSource, string1, string2];
			break;
			
		case TODAssertionTypeValueForFormElementWithName:
			filename = @"AssertValueForFormElementWithName";
			jsSource = [NSString stringWithContentsOfFile:[self pathForJavaScriptResource:filename]];	
			jsSource = [NSString stringWithFormat:jsSource, formIdentifier, string1, string2];
			break;
	}
	
	jsSource = [NSMutableString stringWithString:jsSource];
	[jsSource replaceOccurrencesOfString:@"\"" withString:@"\\\"" options:nil range:NSMakeRange(0, [jsSource length])];

	//NSLog(@"jsSource: %@", jsSource);

	return jsSource;
}


- (NSString *)pathForJavaScriptResource:(NSString *)filename
{	
	NSBundle *bundle = [NSBundle bundleForClass:[self class]];
	return [bundle pathForResource:filename ofType:@"js" inDirectory:@"JavaScript"];
}


- (NSString *)conditionFailedDescription
{
	NSString *string1 = [self objectForParameterKey:@"string1"];
	NSString *string2 = [self objectForParameterKey:@"string2"];
	NSString *formIdentifier = [self objectForParameterKey:@"formIdentifier"];
	
	NSString *fmt = nil;
	NSString *result = nil;
	
	int assertionType = [[self objectForParameterKey:@"assertionType"] intValue];
	
	switch (assertionType) {

		case TODAssertionTypePageTitleEquals:
			fmt = @"WaitForConditionPageTitleEquals failed for '%@'";
			result = [NSString stringWithFormat:fmt, string1];
			break;
			
		case TODAssertionTypePageHasElementWithId:
			fmt = @"WaitForConditionPageHasElementWithId failed for '%@'";
			result = [NSString stringWithFormat:fmt, string1];
			break;
			
		case TODAssertionTypePageDoesntHaveElementWithId:
			fmt = @"WaitForConditionPageDoesntHaveElementWithId failed for '%@'";
			result = [NSString stringWithFormat:fmt, string1];
			break;
			
		case TODAssertionTypePageContainsText:
			fmt = @"WaitForConditionPageContainsText failed for '%@'";
			result = [NSString stringWithFormat:fmt, string1];
			break;
			
		case TODAssertionTypePageDoesntContainText:
			fmt = @"WaitForConditionPageDoesntContainText failed for '%@'";
			result = [NSString stringWithFormat:fmt, string1];
			break;
			
		case TODAssertionTypePageContainsHTML:
			fmt = @"WaitForConditionPagePageContainsHTML failed for '%@'";
			result = [NSString stringWithFormat:fmt, string1];
			break;
			
		case TODAssertionTypePageDoesntContainHTML:
			fmt = @"WaitForConditionPageDoesntContainHTML failed for '%@'";
			result = [NSString stringWithFormat:fmt, string1];
			break;
			
		case TODAssertionTypeValueForFormElementWithId:
			fmt = @"WaitForConditionValueForFormElementWithId failed for id '%@', value '%@'";
			result = [NSString stringWithFormat:fmt, string1, string2];
			break;
			
		case TODAssertionTypeValueForFormElementWithName:
			fmt = @"WaitForConditionValueForFormElementWithName failed for form name '%@', element name '%@', value '%@'";
			result = [NSString stringWithFormat:fmt, formIdentifier, string1, string2];
			break;
			
	}
	
	return result;
}


- (int)currentSecond;
{
	return currentSecond;
}


- (void)setCurrentSecond:(int)n;
{
	currentSecond = n;
}

@end